package com.karson.common.config.rabbitmq;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.RetryInterceptorBuilder;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import java.util.ArrayList;
import java.util.List;

/**
 * @author ZKS
 */

@Configuration
public class RabbitConfig {

    @Value("${spring.rabbitmq.host}")
    private String host;

    @Value("${spring.rabbitmq.port}")
    private int port;

    @Value("${spring.rabbitmq.username}")
    private String username;

    @Value("${spring.rabbitmq.password}")
    private String password;

    public static final String FANOUT_EXCHANGE="fanoutExchange";
    public static final String ACTION_EXCHANGE = "action-exchange";

    public static final String ACTION_QUEUE = "action-queue";
    public static final String QUEUE_USER_MODEL = "user-model-queue";
    public static final String QUEUE_TAG_STATUS = "tag-status-queue";

    public static final String ROUTING_KEY_ACTION = "action";
    public static final String ROUTING_KEY_MODEL = "model";
    public static final String ROUTING_TAG_STATUS = "status";
    public static final String ROUTING_ACTION_RECORD  = "record";

    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host,port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
        return connectionFactory;
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        return template;
    }

    /**
     * 针对消费者配置
     * 1. 设置交换机类型
     * 2. 将队列绑定到交换机
     FanoutExchange: 将消息分发到所有的绑定队列，无routingkey的概念
     HeadersExchange ：通过添加属性key-value匹配
     DirectExchange:按照routingkey分发到指定队列
     TopicExchange:多关键字匹配
     */
    @Bean
    public DirectExchange defaultExchange() {
        return new DirectExchange(ACTION_EXCHANGE);
    }

    /**
     * 获取队列A
     * @return
     */
    @Bean
    public Queue queueAction() {
        //队列持久
        return new Queue(ACTION_QUEUE, true);
    }

    @Bean
    public Queue queueUserModel() {
        //队列持久
        return new Queue(QUEUE_USER_MODEL, true);
    }
    @Bean
    public Queue queueTagStatus() {
        //队列持久
        return new Queue(QUEUE_TAG_STATUS, true);
    }

    /**
     * 队列绑定交换机
     * @return
     */
    @Bean
    public Binding bindingA() {
        return BindingBuilder.bind(queueAction()).to(defaultExchange()).with(RabbitConfig.ROUTING_KEY_ACTION);
    }

    @Bean
    public Binding bindingB(){
        return BindingBuilder.bind(queueUserModel()).to(defaultExchange()).with(RabbitConfig.ROUTING_KEY_MODEL);
    }
    @Bean
    public Binding bindingC(){
        return BindingBuilder.bind(queueTagStatus()).to(defaultExchange()).with(RabbitConfig.ROUTING_TAG_STATUS);
    }

    //配置fanout_exchange
    //fanout只能支持统一广播
    @Bean
    FanoutExchange fanoutExchange() {
        return new FanoutExchange(RabbitConfig.FANOUT_EXCHANGE);
    }

    //把所有的队列都绑定到这个交换机上去
    @Bean
    Binding bindingExchangeA(FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(queueAction()).to(fanoutExchange);
    }
    @Bean
    Binding bindingExchangeB(FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(queueUserModel()).to(fanoutExchange);
    }
}